package handler.store.ind

import service.wx.WxApi
import service.wx.WxSignature
import service.wx.WxUserLocal

import service.store.ind.SockClientInfo

import com.google.zxing.BarcodeFormat
import com.google.zxing.EncodeHintType
import com.google.zxing.MultiFormatWriter
import com.google.zxing.MatrixToImageWriter

import com.google.zxing.common.BitMatrix
import com.google.zxing.client.j2se.MatrixToImageWriter

import org.vertx.groovy.core.buffer.Buffer

import org.paic.d.D

// 微信扫一扫登陆，用公众号
handler.get('/wx/auth/login/index'){req, resp ->
	String token = WxApi.generateNonce()
	resp.render('/store/login.html', [token: token])
}

// 用websocket登陆成功后
handler.get('/wx/auth/login/ok'){req, resp ->
	boolean isAjax = req.params.isAjax != null

	String token = req.params.token
	if(!token){
		if(isAjax){
			resp.json([flag: false, errmsg: 'token-invalid'])
		}else{
			resp.render('/wx/ind/index-error.html', [errmsg: 'token-invalid'])
		}
		return
	}

	def d = D.gen()
	def tokenRow = d.queryMap('select * from wx_user_auth where token = ?', [token])
	if(!tokenRow || tokenRow.status != 1){
		if(isAjax){
			resp.json([flag: false, errmsg: 'token-invalid'])
		}else{
			resp.render('/wx/ind/index-error.html', [errmsg: 'token-invalid'])
		}
		return
	}

	String openid = tokenRow.openid
	def user = WxUserLocal.getUserCached(openid)

	if(user.errcode){
		if(isAjax){
			resp.json([flag: false, errmsg: user.errmsg])
		}else{
			resp.render('/wx/ind/index-error.html', user)
		}
		return
	}

	req.session('wx-user-login', user)

	if(isAjax){
		resp.json(user)
	}else{
		String r = req.params.r
		if(r)
			resp.redirect(r)
		else
			resp.end 'ok'
	}
}

handler.get('/wx/auth/logout'){req, resp ->
	req.session('wx-user-login', '')
	resp.end ''
}


// 微信登录二维码图片
handler.get('/wx/auth/login/qr'){req, resp ->
	String token = req.params.token
	if(!token){
		resp.statusCode = 404
		resp.end ''
		return
	}

	def d = D.gen()
	d.add([token: token], 'wx_user_auth')

	// redirect url
	String r = WxSignature.conf.urlHost + '/wx/auth/login?token=' + token
	r = URLEncoder.encode(r)

	String appid = WxSignature.conf.appid
	// wx auth url
	String url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appid}&redirect_uri=${r}&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect"

	// 生成二维码
	Hashtable<EncodeHintType, String> hints = [:]
	hints.put(EncodeHintType.CHARACTER_SET, 'UTF8')
	
	final int w = 300
	final int h = 300
	BitMatrix bmx = new MultiFormatWriter().encode(url,
				BarcodeFormat.QR_CODE, w, h, hints)

	
	def os = new ByteArrayOutputStream()
	MatrixToImageWriter.writeToStream(bmx, 'png', os)

	byte[] bytes = os.toByteArray()

	resp.headers.set('Content-Type', 'image/png')

	resp.chunked = true
	resp << new Buffer(bytes)
	resp.end()
}

// 扫描登陆
handler.get('/wx/auth/login'){req, resp ->
	String token = req.params.token
	if(!token){
		resp.render('/wx/ind/index-error.html', [errmsg: 'parameter'])
		return
	}

	// check token
	def d = D.gen()
	def tokenRow = d.queryMap('select * from wx_user_auth where token = ?', [token])
	if(!tokenRow || tokenRow.status != 0){
		resp.render('/wx/ind/index-error.html', [errmsg: 'token-invalid'])
		return
	}
	int tokenRowId = tokenRow.id

	String code = req.params.code
	if(!code){
		// reject
//		d.update([id: tokenRowId, status: 10, dd_login: new Date()], 'wx_user_auth', null)
		resp.render('/wx/ind/index-reject.html', [:])
		return
	}

	String ua = req.headers.get('User-Agent')
	boolean isWx = WxApi.isReqFromWx(ua)
	if(isWx){
		def info = WxSignature.getAccessTokenInfo4Auth(code)
		if(info.errcode){
			resp.render('/wx/ind/index-error.html', info)
			return
		}

		def user = WxApi.getUserInfo4Auth(info.access_token, info.openid)
		if(user.errcode){
			resp.render('/wx/ind/index-error.html', user)
			return
		}

		if(user.openid){
			WxUserLocal.update(user)
			d.update([id: tokenRowId, status: 1, dd_login: new Date(), openid: user.openid], 'wx_user_auth', null)
		}

		resp.render('/wx/ind/index-loginok.html', user)
	}else{
		// local test
		String openid = WxSignature.conf.testOpenid
		def user = WxUserLocal.getUserCached(openid)

		d.update([id: tokenRowId, status: 1, dd_login: new Date(), openid: user.openid], 'wx_user_auth', null)
		resp.render('/wx/ind/index-loginok.html', user)
	}

	String sockid = SockClientInfo.inst.get('wx-auth-login-token-' + token + '-sockid')
	if(sockid){
		handlerSockjs.send(sockid, [action: 'loginok'])
	}
}

// client id binding with token
handlerSockjs.add('wx-auth-login-mapping-token'){sock, json ->
	if(!json.token)
		return [flag: false, msg: 'no token']

	SockClientInfo.inst.put('wx-auth-login-token-' + json.token + '-sockid', sock.writeHandlerID)
	[flag: true]
}